﻿// <copyright file="TranslateWrapper.cs" company="Ucaya">
// </copyright>
// <author>Ucaya</author>

namespace Channel9Kinect
{
    namespace SLExtensions.Controls.Animation
    {
        #region

        using System;
        using System.Windows;
        using System.Windows.Media;
        using System.Windows.Media.Animation;

        #endregion

        public class TranslateWrapper
        {
            // Using a DependencyProperty as the backing store for TranslateX.  This enables animation, styling, binding, etc...

            // Using a DependencyProperty as the backing store for TranslatePercentX.  This enables animation, styling, binding, etc...

            #region Constants and Fields

            public static readonly DependencyProperty AnimateTranslateXPercentProperty = DependencyProperty.RegisterAttached("AnimateTranslateXPercent", typeof(double), typeof(TranslateWrapper), new PropertyMetadata(AnimateTranslateXPercentChangedCallback));

            private static readonly DependencyProperty translatePercentXProperty = DependencyProperty.RegisterAttached("TranslatePercentX", typeof(double), typeof(TranslateWrapper), new PropertyMetadata(double.NaN, TranslateChangedCallback));

            // Using a DependencyProperty as the backing store for TranslatePercentY.  This enables animation, styling, binding, etc...
            private static readonly DependencyProperty translatePercentYProperty = DependencyProperty.RegisterAttached("TranslatePercentY", typeof(double), typeof(TranslateWrapper), new PropertyMetadata(double.NaN, TranslateChangedCallback));

            private static readonly DependencyProperty translateXProperty = DependencyProperty.RegisterAttached("TranslateX", typeof(double), typeof(TranslateWrapper), new PropertyMetadata(double.NaN, TranslateChangedCallback));

            // Using a DependencyProperty as the backing store for TranslateY.  This enables animation, styling, binding, etc...
            private static readonly DependencyProperty translateYProperty = DependencyProperty.RegisterAttached("TranslateY", typeof(double), typeof(TranslateWrapper), new PropertyMetadata(double.NaN, TranslateChangedCallback));

            #endregion

            #region Public Properties

            public static DependencyProperty TranslatePercentXProperty
            {
                get
                {
                    return translatePercentXProperty;
                }
            }

            public static DependencyProperty TranslatePercentYProperty
            {
                get
                {
                    return translatePercentYProperty;
                }
            }

            public static DependencyProperty TranslateXProperty
            {
                get
                {
                    return translateXProperty;
                }
            }

            public static DependencyProperty TranslateYProperty
            {
                get
                {
                    return translateYProperty;
                }
            }

            #endregion

            #region Public Methods

            public static double GetAnimateTranslateXPercent(DependencyObject obj)
            {
                return (double)obj.GetValue(AnimateTranslateXPercentProperty);
            }

            public static double GetTranslatePercentX(DependencyObject obj)
            {
                return (double)obj.GetValue(TranslatePercentXProperty);
            }

            public static double GetTranslatePercentY(DependencyObject obj)
            {
                return (double)obj.GetValue(TranslatePercentYProperty);
            }

            public static double GetTranslateX(DependencyObject obj)
            {
                return (double)obj.GetValue(TranslateXProperty);
            }

            public static double GetTranslateY(DependencyObject obj)
            {
                return (double)obj.GetValue(TranslateYProperty);
            }

            public static void SetAnimateTranslateXPercent(DependencyObject obj, double value)
            {
                obj.SetValue(AnimateTranslateXPercentProperty, value);
            }

            public static void SetTranslatePercentX(DependencyObject obj, double value)
            {
                obj.SetValue(TranslatePercentXProperty, value);
            }

            public static void SetTranslatePercentY(DependencyObject obj, double value)
            {
                obj.SetValue(TranslatePercentYProperty, value);
            }

            public static void SetTranslateX(DependencyObject obj, double value)
            {
                obj.SetValue(TranslateXProperty, value);
            }

            public static void SetTranslateY(DependencyObject obj, double value)
            {
                obj.SetValue(TranslateYProperty, value);
            }

            #endregion

            #region Methods

            private static void AnimateTranslateXPercentChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                //TODO: Anim other directions, Store storyboard, Transitions
                var frameworkElement = d as FrameworkElement;
                var sb = new Storyboard();
                var translate = frameworkElement.RenderTransform as TranslateTransform;
                if (translate == null)
                {
                    translate = new TranslateTransform();
                    frameworkElement.RenderTransform = translate;
                }

                if (frameworkElement.ActualHeight != 0 && frameworkElement.ActualWidth != 0)
                {
                    var pcx = (double)e.NewValue;
                    if (!double.IsNaN(pcx))
                    {
                        sb.CreateAnim(translate, "X", new CircleEase { EasingMode = EasingMode.EaseOut }, frameworkElement.ActualWidth * pcx, TimeSpan.FromMilliseconds(300));
                    }
                }

                sb.Begin();
            }

            private static void ApplyTranslate(FrameworkElement frameworkElement)
            {
                var translate = frameworkElement.RenderTransform as TranslateTransform;
                if (translate == null)
                {
                    translate = new TranslateTransform();
                    frameworkElement.RenderTransform = translate;
                }

                double x = GetTranslateX(frameworkElement);
                if (!double.IsNaN(x))
                {
                    translate.X = x;
                }

                double y = GetTranslateY(frameworkElement);
                if (!double.IsNaN(y))
                {
                    translate.Y = y;
                }

                if (frameworkElement.ActualHeight != 0 && frameworkElement.ActualWidth != 0)
                {
                    double pcx = GetTranslatePercentX(frameworkElement);
                    if (!double.IsNaN(pcx))
                    {
                        x = frameworkElement.ActualWidth * pcx;
                        translate.X = x;
                    }

                    double pcy = GetTranslatePercentY(frameworkElement);
                    if (!double.IsNaN(pcy))
                    {
                        y = frameworkElement.ActualHeight * pcy;
                        translate.Y = y;
                    }
                }
            }

            private static void TranslateChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                var fe = d as FrameworkElement;
                ApplyTranslate(fe);
                if (fe != null)
                {
                    fe.SizeChanged += fe_SizeChanged;
                }
            }

            private static void fe_SizeChanged(object sender, SizeChangedEventArgs e)
            {
                ApplyTranslate((FrameworkElement)sender);
            }

            #endregion
        }
    }
}